package com.sys.interceptor;

import com.sys.entity.SysLog;
import com.sys.entity.SysMenu;
import com.sys.entity.SysUser;
import com.bhudy.exception.SysException;
import com.bhudy.exception.SysExceptionCode;
import com.sys.service.SysUserService;
import com.sys.utils.*;
import eu.bitwalker.useragentutils.UserAgent;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;


/**
 * @Author com.bhudy
 * @Description 自定义拦截器
 * @Date 2019-10-30 23:09:37
 */
@Component
public class SysInterceptor implements HandlerInterceptor {

    @Autowired
    private SysUserService sysUserService;
    private SysLog sysLog;
    public static Map<String, SysMenu> idSysMenuMap = new HashMap<>();

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        sysLog = null;
        // 没有加权限验证的注解：放行
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }

        String method = request.getMethod().toLowerCase();
        String url = request.getRequestURI();

        if (url.equals("/error") || url.equals("/sysRedirect")) return true;

        String url2 = null;
        if (url.substring(url.length() - 1).equals("s")) {
            url2 = url.substring(0, url.length() - 1);
        }

        SysMenu sysMenu = SysInterceptor.idSysMenuMap.get(url);
        if (sysMenu == null && url2 != null) sysMenu = SysInterceptor.idSysMenuMap.get(url2);
        if (sysMenu == null || true) return true;

        sysLog = getSysLog(request, sysMenu.getType(), sysMenu.getName());

        SysUser sysUser = ShiroUtils.getUser();
        Subject subject = ShiroUtils.getSubjct(); //创建subject实例

        if (sysUser == null) {
            throw new SysException(SysExceptionCode.CODE_40012);
        } else {
            if (subject.isPermitted(method + ":" + url) || (url2 != null && subject.isPermitted(method + ":" + url2))) {
                return true;
            } else {
                throw new SysException(SysExceptionCode.CODE_40013);
            }
        }
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
        if (sysLog != null && !sysLog.getRequestMethod().equals("GET") && !sysLog.getRequestUrl().matches("/api/.*/.*Import")
                && !sysLog.getRequestUrl().matches("/api/.*/.*Export") && !sysLog.getRequestUrl().matches("/api/.*/.*Upload")
                && !sysLog.getRequestUrl().matches("/api/.*/.*Download")) {
            Long startTime = sysLog.getExecuteTime();
            sysLog.setExecuteTime(System.currentTimeMillis() - startTime);
            sysLog.setIsException(0);
            // MongodbUtils.mongoTemplate.insert(sysLog);

            sysUserService.insert(sysLog);
        }
    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
        if (sysLog != null && e != null && !sysLog.getRequestUrl().matches("/api/.*/.*Import")
                && !sysLog.getRequestUrl().matches("/api/.*/.*Export") && !sysLog.getRequestUrl().matches("/api/.*/.*Upload")
                && !sysLog.getRequestUrl().matches("/api/.*/.*Download")) {
            Long startTime = sysLog.getExecuteTime();
            sysLog.setExecuteTime(System.currentTimeMillis() - startTime);
            sysLog.setIsException(1);
            sysLog.setExceptionInfo(e.getMessage() == null ? "null" : e.getMessage());
            // MongodbUtils.mongoTemplate.insert(sysLog);
            // sysUserService.insert(sysLog);
        }
    }

    public SysLog getSysLog(HttpServletRequest request, Integer type, String title) {
        SysLog sysLog = new SysLog();
        SysUser sysUser = ShiroUtils.getUser(); // 获取操作用户

        sysLog.setLogType(type);
        sysLog.setLogTitle(title);
        sysLog.setExecuteTime(System.currentTimeMillis());
        sysLog.setCreateBy(sysUser.getUserId());
        sysLog.setCreateByName(sysUser.getUserName());
        sysLog.setRequestUrl(request.getRequestURI());
        sysLog.setRequestMethod(request.getMethod());
        sysLog.setRequestParams(request.getQueryString());
        sysLog.setBodyData(HttpHelper.getBodyString(request));
        sysLog.setRemoteAddr(request.getRemoteAddr());
        sysLog.setServerAddr(request.getServerName() + ":" + request.getServerPort());
        sysLog.setUserAgent(request.getHeader("user-agent"));
        sysLog.setCreateDate(new Date());

        UserAgent userAgent = UserAgent.parseUserAgentString(sysLog.getUserAgent());
        sysLog.setDeviceName(userAgent.getOperatingSystem().getName()); // 系统名称
        sysLog.setBrowserName(userAgent.getBrowser().getName()); // 浏览器名称

        return sysLog;
    }

}